#include "encodinghelper.h"
#include "windows.h"

void Gb2312ToUtf8(char* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen) 
{ 
#ifdef WIN32 

    int i = MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, NULL, 0); 
    wchar_t * strSrc = new wchar_t[i+1]; 
    MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, strSrc, i); 
    
    i = WideCharToMultiByte(CP_UTF8, 0, strSrc, -1, NULL, 0, NULL, NULL); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    WideCharToMultiByte(CP_UTF8, 0, strSrc, -1, pstrOut, i, NULL, NULL); 
    delete strSrc; 
#else 
    iconv_t iConv = iconv_open("utf-8", "gb2312"); 
    iconv(iConv, (char **)&pstrIn, (size_t *)&dwInLen, (char **)&pstrOut, (size_t *)&dwOutLen); 
    iconv_close(iConv); 
#endif 
} 

//utf8תgb2312 
void Utf8ToGb2312(char* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    int i = MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, NULL, 0); 
    wchar_t * strSrc = new wchar_t[i+1]; 
    MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, strSrc, i); 
    
    i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    WideCharToMultiByte(CP_ACP, 0, strSrc, -1, pstrOut, i, NULL, NULL); 
    delete strSrc; 
#else 
    iconv_t iConv = iconv_open("gb2312", "utf-8"); 
    iconv(iConv, (char **)&pstrIn, (size_t *)&dwInLen, (char **)&pstrOut, (size_t *)&dwOutLen); 
    iconv_close(iConv); 
#endif 
}

//gb2312תUnicode 
void Gb2312ToUnicode(wchar_t* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    u32 i = MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, NULL, 0); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, pstrOut, i); 
#else 
    iconv_t iConv = iconv_open("unicode", "gb2312"); 
    iconv(iConv, (char**)pstrIn, &dwInLen, (char**)pstrOut, &dwOutLen); 
    iconv_close(iConv); 
#endif 
} 

//UnicodeתGb2312 
void UnicodeToGb2312(char* pstrOut, u32 dwOutLen, const wchar_t* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    u32 i = WideCharToMultiByte(CP_ACP, 0, pstrIn, -1, NULL, 0, NULL, NULL); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    WideCharToMultiByte(CP_ACP, 0, pstrIn, -1, pstrOut, i, 0, 0); 
#else 
    iconv_t iConv = iconv_open("gb2312", "unicode"); 
    iconv(iConv, (char**)pstrIn, &dwInLen, (char**)pstrOut, &dwOutLen); 
    iconv_close(iConv); 
#endif 
} 

//utf8תUnicode 
void Utf8ToUnicode(wchar_t* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    u32 i = MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, NULL, 0); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, pstrOut, i); 
#else 
    iconv_t iConv = iconv_open("unicode", "utf-8"); 
    iconv(iConv, (char**)pstrIn, &dwInLen, (char**)pstrOut, &dwOutLen); 
    iconv_close(iConv); 
#endif 
}

string gbToUtf8(const char* pstrIn)
{
    int len = strlen(pstrIn);
    char buff[128];
    Gb2312ToUtf8(buff, 128, pstrIn, len);
    return string(buff);
}

string utToGb23(const char* pstrIn)
{
    int len = strlen(pstrIn);
    char*p = new char[len+1];
    Utf8ToGb2312(p, len + 1, pstrIn, len);
    return string(p);
}